1 /*
2 Copyright: Marcelo S. N. Mancini (Hipreme|MrcSnm), 2018 - 2021
3 License:   [https://creativecommons.org/licenses/by/4.0/|CC BY-4.0 License].
4 Authors: Marcelo S. N. Mancini
5 
6 	Copyright Marcelo S. N. Mancini 2018 - 2021.
7 Distributed under the CC BY-4.0 License.
8    (See accompanying file LICENSE.txt or copy at
9 	https://creativecommons.org/licenses/by/4.0/
10 */
11 module hip.hiprenderer.shader.var_packing;
12 import hip.hiprenderer.shader;
13 import hip.hiprenderer.shader.shadervar;
14 import hip.error.handler;
15 
16 struct VarPosition
17 {
18     size_t startPos;
19     size_t endPos;
20     size_t size;
21 }
22 
23 /**
24 *   Uses the OpenGL's GLSL Std 140 for getting the variable position.
25 *   This function must return what is the end position given the last variable size.
26 */
27 VarPosition glSTD140(ref ShaderVar* v, size_t lastAlignment = 0, bool isLast = false)
28 {
29     size_t size = v.varSize;
30     
31     if(lastAlignment == 0)
32         return VarPosition(0,size,size);
33 
34     size_t size4 = size*4;
35 
36     //((8 % 16) > (8+8) % 16  || 8 % 16 == 0) && (8+8 % 16 != 0)
37     // 8 + (8 % 16) + 8 
38     
39     if((lastAlignment % size4 > (lastAlignment+size) % size4 || size % size4 == 0) && (lastAlignment+size) % size4 != 0)
40     {
41         size_t startPos = lastAlignment;
42         if(startPos % size4 != 0) startPos = startPos + (size4 - (startPos % size4));
43 
44         return VarPosition(startPos, startPos+size, size);
45     }
46     
47     return VarPosition(lastAlignment, lastAlignment + size, size);
48 }
49 
50 /**
51 *   Uses the OpenGL's GLSL Std 140 for getting the variable position.
52 *   This function must return what is the end position given the last variable size.
53 */
54 VarPosition dxHLSL4(ref ShaderVar* v, size_t lastAlignment = 0, bool isLast = false)
55 {
56     size_t newN = v.varSize;
57     if(isLast)
58     {
59         size_t startPos = lastAlignment;
60         if(startPos % 16 != 0) startPos = startPos + (16 - (startPos % 16));
61         size_t endPos = startPos+newN;
62         if(endPos % 16 != 0) endPos = endPos + (16 - (endPos % 16));
63         return VarPosition(startPos, endPos, newN);
64     }
65     if(lastAlignment == 0)
66         return VarPosition(0,newN,newN);
67 
68    
69     size_t n4 = newN*4;
70 
71     //((8 % 16) > (8+8) % 16  || 8 % 16 == 0) && (8+8 % 16 != 0)
72     // 8 + (8 % 16) + 8 
73     
74     if((lastAlignment % n4 > (lastAlignment+newN) % n4 || newN % n4 == 0) && (lastAlignment+newN) % n4 != 0)
75     {
76         size_t startPos = lastAlignment+ (lastAlignment % n4);
77         return VarPosition(startPos, startPos+newN, newN);
78     }
79     
80     return VarPosition(lastAlignment, lastAlignment + newN, newN);
81 }
82 
83 VarPosition nonePack(ref ShaderVar* v, size_t lastAlignment = 0, bool isLast = false)
84 {
85     return VarPosition(0,0,0);
86 }